﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using _MetalSlug.MyCharacters.Characters;
using _MetalSlug.Weapons.Units;
using _MetalSlug.Mission;
using _MetalSlug.Mementoes;

namespace _MetalSlug.Soldiers.Units
{
    public abstract class Enemy : VisibleGameEntity
    {
        public const int DelayShotTime = 5;
        
        protected int id;
        public int Id
        {
            get { return id; }
        }
        

        protected int _hp;
        protected float time;
        protected bool isDead;
        protected Segment distanceChase;
        protected Segment distanceShoot;
        protected int distanceFlip;
        Vector2 charDirection;

        
        protected List<Bullet> bullets;

        public List<Bullet> Bullets
        {
            get { return bullets; }
            set { bullets = value; }
        }

        protected CURRENT_ACTIVITY activity;

        public CURRENT_ACTIVITY Activity
        {
            get { return activity; }
            set 
            {
                if(activity != value|| CurrentTextures == null)
                {
                    IndexCurrent = 0;
                    switch(value)
                    {
                        case CURRENT_ACTIVITY.DIE:
                            CurrentTextures = DieTexture2Ds;
                            break;

                        case CURRENT_ACTIVITY.STAND:
                            CurrentTextures = StandTexture2Ds;
                            break;

                        case CURRENT_ACTIVITY.RUN:
                            CurrentTextures = RunTexture2Ds;
                            break;

                        case CURRENT_ACTIVITY.SHOOT:
                            CurrentTextures = ShotTexture2Ds;
                            break;

                    }
                }

                activity = value;  
            }
        }

        public enum CURRENT_ACTIVITY
        {
            STAND,
            SHOOT,
            DIE,
            RUN
        }

        public enum TYPE_SOLDIER
        {
            AK_SOLDIER,
            BAZOKA_SOLDIER,
            MINIGUN_SOLDIER,
            HELICOPER,
            TYCOON
        }

        RESOURCE_FACE facing;
        public RESOURCE_FACE Facing
        {
            get { return facing; }
            set
            {
                facing = value;
                if (Facing == RESOURCE_FACE.LEFT)
                {
                    CharDirection = -Vector2.UnitX;
                }
                else
                {
                    CharDirection = Vector2.UnitX;
                }
            }
        }
        public enum RESOURCE_FACE
        {
            LEFT,
            RIGHT
        }

        protected TYPE_SOLDIER type;

        public TYPE_SOLDIER Type
        {
            get { return type; }
            set { type = value; }
        }

        public struct Segment
        {
            public int Max;
            public int Min;
        }

        protected List<Texture2D> currentTextures;
        public List<Texture2D> CurrentTextures
        {
            get { return currentTextures; }
            set { currentTextures = value; }
        }

        protected int indexCurrent;

        public int IndexCurrent
        {
            get { return indexCurrent; }
            set { indexCurrent = value; }
        }

        protected List<Texture2D> standTexture2Ds;
        public List<Texture2D> StandTexture2Ds
        {
            get { return standTexture2Ds; }
            set { standTexture2Ds = value; }
        }

        protected List<Texture2D> dieTexture2Ds;
        public List<Texture2D> DieTexture2Ds
        {
            get { return dieTexture2Ds; }
            set { dieTexture2Ds = value; }
        }
        
        protected List<Texture2D> runTexture2Ds;
        public List<Texture2D> RunTexture2Ds
        {
            get { return runTexture2Ds; }
            set { runTexture2Ds = value; }
        }
        
        protected List<Texture2D> shotTexture2Ds;
        public List<Texture2D> ShotTexture2Ds
        {
            get { return shotTexture2Ds; }
            set { shotTexture2Ds = value; }
        }

        public int Hp
        {
            get { return _hp; }
            set 
            {
                if (Hp > value && value > 0)
                {
                    ColorDisplay = Color.Red;
                }
                else
                {
                    ColorDisplay = Color.White;
                }

                _hp = value;
                if (Hp <= 0)
                {
                    Activity = CURRENT_ACTIVITY.DIE;
                } 
            }
        }

        public bool IsDead
        {
            get { return isDead; }
            set { isDead = value; }
        }
        public float Time
        {
            get { return time; }
            set { time = value; }
        }

        public Segment DistanceChase
        {
            get { return distanceChase; }
            set { distanceChase = value; }
        }

        public Segment DistanceShoot
        {
            get { return distanceShoot; }
            set { distanceShoot = value; }
        }

        public int DistanceFlip
        {
            get { return distanceFlip; }
            set { distanceFlip = value; }
        }

        protected Color colorDisplay;

        public Color ColorDisplay
        {
            get { return colorDisplay; }
            set 
            { 
                colorDisplay = value;
                if (ColorDisplay == Color.White)
                {
                    DelayShot = -1;
                }
                else
                {
                    DelayShot = 0;
                }
            }
        }

        protected int delayShot;

        public int DelayShot
        {
            get { return delayShot; }
            set { delayShot = value; }
        }

        public Vector2 CharDirection
        {
            get { return charDirection; }
            set { charDirection = value; }
        }

       virtual  public void Update(GameTime gameTime, MyMap map, MyCharacter Hero)
       {
           if (Hero.Hp > 0)
           {
               if (Hp > 0)
               {
                   UpdateActivity(Hero);
               }
           }
           else
           {
               if(Activity != CURRENT_ACTIVITY.STAND)
               {
                   Activity = CURRENT_ACTIVITY.STAND;
               }
           }

           UpdateBullet(gameTime, map,Hero);
           UpdateTexture();
       }

       public virtual Vector2 Move(KeyboardState keyBoardState, Vector2 ufo,int speed)
       {
           if (keyBoardState.IsKeyDown(Keys.A))
           {
               ufo.X += speed;
           }
           if (keyBoardState.IsKeyDown(Keys.D))
           {
               ufo.X -= speed;
           }
           return ufo;
       }

       public virtual void LoadContent()
       {
           
       }

       public virtual void InitialAttribute(Vector2 topleft, Vector2 size)
       {
           Activity = CURRENT_ACTIVITY.STAND;
           Facing = RESOURCE_FACE.LEFT;
           TopLeft = topleft;
           Size = size;
           LoadContent();
           CharDirection = -Vector2.UnitX;
       }

       public override void Draw(SpriteBatch spriteBatch)
       {
           if (!(Activity == CURRENT_ACTIVITY.DIE && IndexCurrent == DieTexture2Ds.Count - 1))
           {
               foreach (Bullet bullet in Bullets)
               {
                   bullet.Draw(spriteBatch);
               }

               Vector2 newPos = TopLeft - new Vector2(GameUtil.GamePivot.PivotPoint, 0);
               if (Facing == RESOURCE_FACE.RIGHT)
               {
                   spriteBatch.Draw(CurrentTextures[IndexCurrent], new Rectangle((int)newPos.X, (int)newPos.Y, (int)Size.X, (int)Size.Y), null, ColorDisplay, 0, Vector2.Zero, SpriteEffects.FlipHorizontally, 0f);
               }
               else
               {
                   spriteBatch.Draw(CurrentTextures[IndexCurrent], new Rectangle((int)newPos.X, (int)newPos.Y, (int)Size.X, (int)Size.Y), ColorDisplay);
               }
           }
           else
           {
               isDead = true;
           }
       }

       public virtual Enemy Clone(int ID, Vector2 topleft)
       {
           return null;
       }

       public virtual void Copy(Enemy origin, Vector2 topleft)
       {
           Type = origin.Type;
           TopLeft = topleft;
           Size = origin.Size; 
           StandTexture2Ds = origin.StandTexture2Ds;
           ShotTexture2Ds = origin.ShotTexture2Ds;
           RunTexture2Ds = origin.RunTexture2Ds;
           DieTexture2Ds = origin.DieTexture2Ds;
           Hp = origin.Hp;
           ColorDisplay = Color.White;
           Bullets = new List<Bullet>();
           DistanceFlip = origin.DistanceFlip;
           DistanceShoot = origin.DistanceShoot;
           DistanceChase = origin.DistanceChase;
           Activity = origin.Activity;
           Facing = RESOURCE_FACE.LEFT;
           if (Size == Vector2.Zero)
           {
               Size = new Vector2(CurrentTextures[IndexCurrent].Width, CurrentTextures[IndexCurrent].Height);
           }
       }

       public virtual void RestoreMemento(IMemento OldMemento)
       {
           SoldierMemento MyMemento = (SoldierMemento)OldMemento;
           Activity = MyMemento.CurrentActivity;
           Facing = MyMemento.CurrentFacing;
           Hp = MyMemento.Hp;
           TopLeft = MyMemento.TopLeft;
       }
       

       public virtual void UpdateTexture()
       {
           Time++;
           if (Hp > 0)
           {
               if (time % 50 == 0 && Activity == CURRENT_ACTIVITY.STAND)
               {
                   NextFrame();
               }

               if (time % 10 == 0)
               {
                   NextFrame();
               }

               if(DelayShot != -1)
               {
                   DelayShot++;
                   if(DelayShot > DelayShotTime)
                   {
                       ColorDisplay = Color.White;
                   }
               }
           }
           else
           {
               if (Activity != CURRENT_ACTIVITY.DIE)
               {
                   Activity = CURRENT_ACTIVITY.DIE;
               }

               if (time % 10 == 0 && IndexCurrent != CurrentTextures.Count - 1)
               {
                   NextFrame();
               }
           }
       }


       public virtual void UpdateActivity(MyCharacter Hero)
       {
           if(Hero.Hp <= 0)
           {
               Activity = CURRENT_ACTIVITY.STAND;
               return;
           }

           Vector2 ufo = TopLeft;
           if (Math.Abs(Hero.TopLeft.X - TopLeft.X) < DistanceChase.Max && 
               Math.Abs(Hero.TopLeft.X - TopLeft.X) > DistanceChase.Min)
           {
               Activity = CURRENT_ACTIVITY.RUN;
               if (Hero.TopLeft.X - TopLeft.X > DistanceFlip)
               {
                   ufo.X += 2;
               }
               else
               {
                   ufo.X -= 2;
               }
               TopLeft = ufo;
           }

           

           if (Math.Abs(Hero.TopLeft.X - TopLeft.X) < DistanceShoot.Max && 
               Math.Abs(Hero.TopLeft.X - TopLeft.X) >= DistanceShoot.Min)
           {
               Activity = CURRENT_ACTIVITY.SHOOT;
               if (IndexCurrent == ShotTexture2Ds.Count-1 && Activity == CURRENT_ACTIVITY.SHOOT)
               {
                   Shoot();
                   Activity = CURRENT_ACTIVITY.STAND;
               }
           }

           if (Hero.TopLeft.X - TopLeft.X > DistanceFlip)
           {
               Facing = RESOURCE_FACE.RIGHT;
           }
           else
           {
               Facing = RESOURCE_FACE.LEFT;
           }

       }

       protected virtual void Shoot()
       {

       }

       public virtual void UpdateBullet(GameTime theGameTime, MyMap map, MyCharacter Hero)
       {
           Bullets.RemoveAll(item => !item.Visible);
           foreach (Bullet bullet in Bullets)
           {
               bullet.Update(theGameTime, map, Hero);
           }  
       }

       public void NextFrame()
       {
           IndexCurrent = (IndexCurrent + 1) % CurrentTextures.Count;
       }
    }
}
